﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace LG.Common
{

    public static class DataCache
    {
        public static readonly TimeSpan PersistentTimeSpan = TimeSpan.FromDays(1000);

        public static T Add<T>(IGetDataCachePath  key, T entry, TimeSpan timeSpan)
        {
            T obj = Get<T>(key);
            if (obj != null)
            {
                return obj;
            }
            Set<T>(key, entry, timeSpan);
            return entry;
        }

        public static T Get<T>(IGetDataCachePath key) 
        {
            string path = key.GetPath();
            if (!File.Exists(path))
            {
                return default(T);
            }
            CacheItem<T> item = SerializeHelper.BinaryDeserialize<CacheItem<T>>(path);
            if (item.Expiry <= DateTime.Now)
            {
                Remove(key);
                return default(T);
            }
            return item.Item;
        }

        public static void Set<T>(IGetDataCachePath key , T entry, TimeSpan timeSpan)
        {
            CacheItem<T> item = new CacheItem<T>(entry,DateTime.Now.Add(timeSpan));
            string path = key.GetPath();
            CheakPath(path);
            SerializeHelper.BinarySerialize(item, path);
        }

        public static void Remove(IGetDataCachePath key)
        {
            string path = key.GetPath();
            if (File.Exists(path))
            {
                File.Delete(path);
            }
        }

        private static void CheakPath(string path)
        {
            string directory = Path.GetDirectoryName(path);
            if (!Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }
        }


        [Serializable]
        private class CacheItem<T>
        {
            public DateTime Expiry { get; set; }
            public T Item { get; set; }
            public CacheItem(T entry, DateTime expiry)
            {
                Item = entry;
                Expiry = expiry;
            }
        }
    }
}
